#ifndef MUTEX_HPP_
# define MUTEX_HPP_

# include <pthread.h>
# include "Utils/macros.hpp"

namespace wrappers {
namespace pthread {

/*! \class Mutex
 * \brief Wrapper for pthread mutexes
 *
 * This class provide an object-oriented wrapper for pthread's mutexes.
 * Copies of this class cannot be made.
 */
class Mutex {
public:
  /*! \enum eState
   * Describe the mutex current state
   */
  typedef enum {
	FREE, /*!< The mutex is free */
	LOCKED /*!< The mutex is locked */
  } eState;

  /*! Default constructor */
  Mutex();
  /*! Destructor */
  virtual ~Mutex();

  /*! Lock the mutex */
  virtual void Lock();

  /*! Try to lock the mutex
   * \return true if a lock on the mutex is acquired, otherwise, return false
   */
  virtual bool TryLock();

  /*! Unlock the mutex */
  virtual void Unlock();

  /*! Get the mutex current state
   * \return The mutex state
   */
  virtual eState GetState() const;

  /*! Get the \a pthread_mutex_t associated with this object.
   * If you manually lock or unlock the returned mutex, this class may not
   * be functional anymore.
   * \return a reference on the pthread_mutex_t associated with this object
   */
  pthread_mutex_t &GetMutex();

protected:
  /*! Disallow copy constructor and assignment operator */
  DISALLOW_COPY_AND_ASSIGN(Mutex);

  pthread_mutex_t mMutex; /*!< Pthread mutex */
  eState mState; /*!< Current mutex state */
};

}
}

#endif /* !MUTEX_HPP_ */
